from typing import Any

from typing_inspect import get_args, is_literal_type

from zkl_pyutils_serialization.basics import get_context_tag_value
from zkl_pyutils_serialization.convert import registry
from zkl_pyutils_serialization.convertors.common import PyObjectFormat
from zkl_pyutils_serialization.tags import DstFormat, DstTypehint, SrcFormat, SrcType
from .format import JsonValueFormat


@registry.register({SrcFormat: PyObjectFormat, DstFormat: JsonValueFormat})
def literal_serializer(value: Any) -> Any:
    typehint = get_context_tag_value(SrcType)
    if not is_literal_type(typehint):
        raise NotImplementedError

    options = get_args(typehint)
    if value not in options:
        raise NotImplementedError
    return value


@registry.register({SrcFormat: JsonValueFormat, DstFormat: PyObjectFormat})
def literal_deserializer(value: Any) -> Any:
    typehint = get_context_tag_value(DstTypehint)
    if not is_literal_type(typehint):
        raise NotImplementedError

    options = get_args(typehint)
    if value not in options:
        raise NotImplementedError
    return value
